home *** CD-ROM | disk | FTP | other *** search
- /*
- callbacks for message ports
- 5/2/93 Bernhard Fastenrath
- */
-
- #include <dos.h>
- #include <signal.h>
- #include <dos/dos.h>
- #include <exec/types.h>
- #include <pragmas/exec_pragmas.h>
-
- #include "callbacks.h"
-
- static struct CbPort *find_cbport (struct MsgPort *port);
-
- static struct MinList port_list = { NULL, NULL, NULL };
- static ULONG signals = SIGBREAKF_CTRL_C;
-
- ULONG free_signals = 0;
- callback signal_callback = NULL;
-
- void
- RemoveAllCallbacks ()
- {
- struct Callback *cnode;
- struct CbPort *pnode;
-
- if (!port_list.mlh_Head) return;
-
- while (pnode = RemTail (&port_list))
- {
- while (cnode = RemTail (&pnode -> callbacks))
- free (cnode);
-
- free (pnode);
- }
- signals = SIGBREAKF_CTRL_C;
- }
-
- void
- RemoveCallback (struct Callback *cb)
- {
- struct CbPort *node;
-
- Remove (cb);
- free (cb);
-
- if (EmptyMinList (&cb -> cbport -> callbacks)) {
- Remove (cb -> cbport);
- free (cb -> cbport);
- }
- signals = SIGBREAKF_CTRL_C | free_signals;
- for (node = port_list.mlh_Head; node -> node.mln_Succ; node = node -> node.mln_Succ)
- signals |= node -> sig;
- }
-
- struct Callback *
- AddPortCallback (struct MsgPort *port, callback fun, ULONG class)
- {
- struct Callback *new_cb;
- struct CbPort *pn;
-
- if (!port_list.mlh_Head)
- InitListHeader (&port_list);
-
- if (!(pn = find_cbport (port)))
- return NULL;
-
- if (!(new_cb = Malloc (struct Callback)))
- return NULL;
-
- new_cb -> class = class;
- new_cb -> function = fun;
- new_cb -> cbport = pn;
-
- AddHead (&pn -> callbacks, new_cb);
-
- return new_cb;
- }
-
- void
- SetSignalCallback (ULONG signal_mask, callback fun)
- {
- free_signals = signal_mask;
- signals |= free_signals;
- signal_callback = fun;
- }
-
- void
- AppMainLoop ()
- {
- struct IntuiMessage *msg;
- ULONG received = 0;
- struct CbPort *pnode;
- struct Callback *cnode;
-
- while (!(received & SIGBREAKF_CTRL_C))
- {
- received = Wait (signals);
-
- if (free_signals & received)
- signal_callback (received);
-
- for (pnode = port_list.mlh_Head; pnode -> node.mln_Succ; pnode = pnode -> node.mln_Succ)
- {
- while (msg = GetMsg (pnode -> port))
- {
- for (cnode = pnode -> callbacks.mlh_Head; cnode -> node.mln_Succ; cnode = cnode -> node.mln_Succ)
- {
- /* cnode -> class has to be zero for non-IntuiMessages which
- don't have a `class' field following the message struct!
- */
- if (!cnode -> class || msg -> Class == cnode -> class)
- if (cnode -> function (msg, cnode)) {
- msg = NULL;
- break;
- }
- }
- if (msg && msg -> ExecMessage.mn_ReplyPort != pnode -> port)
- ReplyMsg (msg);
- }
- }
- }
- #if 0
- printf ("AppMainLoop: User Break detected.\n");
- #endif
- }
-
- void
- InitListHeader (struct MinList *list)
- {
- list -> mlh_Head = &list -> mlh_Tail;
- list -> mlh_TailPred = &list -> mlh_Head;
- list -> mlh_Tail = 0;
- }
-
- static struct CbPort*
- find_cbport (struct MsgPort *port)
- {
- struct CbPort *pn;
-
- for (pn = port_list.mlh_Head; pn -> node.mln_Succ; pn = pn -> node.mln_Succ)
- if (pn -> port == port)
- return pn;
-
- if (!(pn = Malloc (struct CbPort)))
- return NULL;
-
- pn -> port = port;
- signals |= pn -> sig = 1L << port -> mp_SigBit;
-
- InitListHeader (&pn -> callbacks);
-
- AddHead (&port_list, (struct MinNode *) pn);
-
- return pn;
- }
-